#include "stdafx.h"
/// Copyright 2012, Alex Averian, Yonan Research
/// Released under BSD Licence


#include "qdragdrop.h"
using namespace micro::dragdrop;



HRESULT QDropTarget::DragEnter( IDataObject * pdtobj, DWORD   grfKeyState   , POINTL p, DWORD * pdwEffect )
{
    // leave *pdwEffect unchanged, we support all operations
    POINT pt = { p.x, p.y };

    if ( m_pdragHelper )
    {
        m_pdragHelper->DragEnter( m_hwnd, pdtobj, &pt, *pdwEffect );
    }

    SetInterface( &m_pdtobj, pdtobj );
    OnQueryDrop( grfKeyState, pdwEffect );
    return  OnDragEnter( pt ); //S_OK;
}

HRESULT QDropTarget::DragOver( DWORD   grfKeyState  , POINTL p, DWORD * pdwEffect )
{
    POINT pt = { p.x, p.y };

    // leave *pdwEffect unchanged, we support all operations
    if ( m_pdragHelper )
    {
        m_pdragHelper->DragOver( &pt, *pdwEffect );
    }

    OnQueryDrop( grfKeyState, pdwEffect );
    return OnDragOver( pt, *pdwEffect ); //S_OK;
}

HRESULT QDropTarget::DragLeave()
{
    if ( m_pdragHelper )
    {
        m_pdragHelper->DragLeave();
    }

    //ClearDropTip(m_pdtobj);

    HRESULT hr = OnDragLeave();
    SafeRelease( &m_pdtobj );
    return hr;
}

HRESULT QDropTarget::Drop( IDataObject * pdtobj, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect )
{
    if ( m_pdragHelper )
    {
        POINT ptT = { pt.x, pt.y };
        m_pdragHelper->Drop( pdtobj, &ptT, *pdwEffect );
    }



    OnQueryDrop( grfKeyState, pdwEffect );
    HRESULT   hr = OnDrop( pdtobj,  grfKeyState, *pdwEffect );


    SafeRelease( &m_pdtobj );
    return hr;
}



//virtual generic
HRESULT QDropTarget::OnQueryDrop( DWORD grfKeyState,  DWORD * dwAllowed )
{
    DWORD dwEffect = 	DROPEFFECT_NONE;//DROPEFFECT_COPY	 | DROPEFFECT_MOVE	| DROPEFFECT_LINK;

    // 1. check "pt" -> do we allow a drop at the specified coordinates?
    // 2. work out that the drop-effect should be based on grfKeyState


    if ( ::GetKeyState( VK_MENU ) & 0x8000 )
    {
        dwEffect = *dwAllowed & DROPEFFECT_LINK;
    }
    else
        if ( grfKeyState & MK_CONTROL )
        {
            dwEffect = *dwAllowed & DROPEFFECT_COPY;
        }
        else
            if ( grfKeyState & MK_SHIFT )
            {
                dwEffect = *dwAllowed & DROPEFFECT_MOVE;
            }

    //else
    //    dwEffect = *dwAllowed & DROPEFFECT_COPY;


    // 3. no key-modifiers were specified (or drop effect not allowed), so
    //    base the effect on those allowed by the dropsource
    if ( dwEffect == DROPEFFECT_NONE )
    {
        if ( *dwAllowed & DROPEFFECT_LINK )
            dwEffect = DROPEFFECT_LINK;

        if ( *dwAllowed & DROPEFFECT_MOVE )
            dwEffect = DROPEFFECT_MOVE;

        if ( *dwAllowed & DROPEFFECT_COPY )
            dwEffect = DROPEFFECT_COPY;
    }

    //last chance
    if ( dwEffect == DROPEFFECT_NONE )
        dwEffect = DROPEFFECT_COPY;


    *dwAllowed = dwEffect;

    return S_OK;
}







//////////////////////////////////////////////////////////////////////
// QDataObject Class
//////////////////////////////////////////////////////////////////////
//
// IFACEMETHODIMP QDataObject::SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
// {
//     HRESULT hr = _EnsureShellDataObject();
//     if (SUCCEEDED(hr))
//     {
//         hr = m_phelpShell->SetData(pformatetc, pmedium, fRelease);
//     }
//     return hr;
// }
//
// STDMETHODIMP QDataObject::QueryGetData(FORMATETC *pformatetc)
// {
//     HRESULT hr = S_FALSE;
// /*
// 	if (pformatetc->cfFormat == CF_UNICODETEXT)
//     {
//         hr = S_OK;
//     }
//     else
// */
// 	if (SUCCEEDED(_EnsureShellDataObject()))
//     {
//         hr = m_phelpShell->QueryGetData(pformatetc);
//     }
//     return hr;
// }
//
// STDMETHODIMP QDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFormatEtc)
// {
//     *ppenumFormatEtc = nullptr;
//     HRESULT hr = E_NOTIMPL;
//     if (dwDirection == DATADIR_GET)
//     {
//         FORMATETC rgfmtetc[] =
//         {
//             // the order here defines the accuarcy of rendering
//              { CF_UNICODETEXT,   nullptr, 0,  0, TYMED_HGLOBAL },
// 			 { CF_HDROP,         nullptr, 0,  0, TYMED_HGLOBAL },
// 		};
//         hr = SHCreateStdEnumFmtEtc(ARRAYSIZE(rgfmtetc), rgfmtetc, ppenumFormatEtc);
//     }
//     return hr;
// }
//
